package com.jy.api.domain;

import com.aliyun.mns.client.CloudQueue;
import com.aliyun.mns.client.MNSClient;
import com.aliyun.mns.model.Message;
import com.jy.api.dao.OrderDao;
import com.jy.api.dao.StorePayDao;
import com.jy.api.payReq.AllPayBaseQueryResult;
import com.jy.api.payReq.AllPayRefundQueryResult;
import com.jy.api.payReq.AllPayReverseResult;
import com.jy.api.service.PaymentService;
import com.jy.api.service.impl.*;
import com.jy.api.signUpReq.web.WebCancelPayReq;
import com.jy.api.util.RedisSyncLocker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * Created by lihu on 2017/12/29.
 */
@Component
@Profile("!dev")
@Slf4j
public class AliyunMNSConsume {
    private MNSClient client;

    private String cloudQueue;

    private PaymentService paymentService;
    @Autowired
    private StorePayDao storePayDao;
    @Autowired
    private HSServiceImpl hsService;
    @Autowired
    private JLServiceImpl jlService;
    @Autowired
    private SaoBeiServiceImpl saoBeiService;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private HuiFuServiceImpl huiFuService;
    @Autowired
    private SuiXinFuServiceImpl suiXinFuService;
    @Autowired
    private RedisSyncLocker redisSyncLocker;

    @EventListener(ApplicationReadyEvent.class)
    public void process() {
        CloudQueue queue = client.getQueueRef(cloudQueue);
        while (true) {
            try {
                Message popMsg = queue.popMessage(2);
                log.info("AliyunMNSConsume process: {}", popMsg);
                if (popMsg != null) {
                    String[] s = popMsg.getMessageBody().split(":");
                    if (s[0].equals("refund")) {
                        // 退款结果查询
                        Order order = orderDao.findByIdOrPayOrderIdAndAmountGreaterThan(s[1], s[1], 0);
                        StorePay storePay = storePayDao.findByStoreIdAndStartEnabled(order.getStoreId(), true);
                        AllPayRefundQueryResult result;
                        switch (storePay.getChannel()) {
                            case JL:
                                result = jlService.JlQueryRefundResult(order.getId());
                                if (result.isSuccess()) {
                                    log.debug("Succeed to refund order: {}", result.getOutRefundNo());
                                    jlService.JlcallbackForThirdPartyRefundSuccess(result);
                                } else {
                                    jlService.JlcallbackForThirdPartyRefundFail(result);
                                }
                                queue.deleteMessage(popMsg.getReceiptHandle());
                                break;
                            case HUI_SHANG:
                                result = hsService.queryRefundResult(order.getId());
                                if (result.isProcessing()) {
                                    continue;
                                } else {
                                    if (result.isSuccess()) {
                                        log.debug("Succeed to refund order: {}", result.getOutRefundNo());
                                        hsService.callbackForThirdPartyRefundSuccess(result);
                                    } else {
                                        hsService.callbackForThirdPartyRefundFail(result);
                                    }
                                    queue.deleteMessage(popMsg.getReceiptHandle());
                                }
                                break;
                            case SAO_BEI:
                                result = saoBeiService.saoBeiRefundQuery(storePay, order);
                                if (result.isProcessing()) {
                                    continue;
                                } else {
                                    if (result.isSuccess()) {
                                        log.debug("Succeed to refund order: {}", result.getOutRefundNo());
                                        saoBeiService.callbackForThirdPartyRefundSuccess(result);
                                    } else {
                                        saoBeiService.callbackForThirdPartyRefundFail(result);
                                    }
                                    queue.deleteMessage(popMsg.getReceiptHandle());
                                }
                                break;
                            case HUI_FU:
                                result = huiFuService.huifuRefundQuery(storePay, order);
                                if (result.isProcessing()) {
                                    continue;
                                } else {
                                    if (result.isSuccess()) {
                                        log.debug("Succeed to refund order: {}", result.getOutRefundNo());
                                        huiFuService.callbackForThirdPartyRefundSuccess(result);
                                    } else {
                                        huiFuService.callbackForThirdPartyRefundFail(result);
                                    }
                                    queue.deleteMessage(popMsg.getReceiptHandle());
                                }
                                break;
                            case SUI_XIN_FU:
                                result = suiXinFuService.suixingfuRefundQuery(storePay, order);
                                if (result.isProcessing()) {
                                    continue;
                                } else {
                                    if (result.isSuccess()) {
                                        log.debug("Succeed to refund order: {}", result.getOutRefundNo());
                                        suiXinFuService.suixinfuCallbackForThirdPartyRefundSuccess(result);
                                    } else {
                                        suiXinFuService.suixinfuCallbackForThirdPartyRefundFail(result);
                                    }
                                    queue.deleteMessage(popMsg.getReceiptHandle());
                                }
                                break;
                        }

                    } else {
                        // 支付结果查询
                        String orderId = popMsg.getMessageBody();
                        String orgOrderId = orderId;
                        if (orderId.length() > 32) {
                            orgOrderId = orderId.substring(4);
                        }
                        String finalOrgOrderId = orgOrderId;
                        redisSyncLocker.idLock(finalOrgOrderId, (o) -> {
                            Order order = orderDao.findByIdOrPayOrderIdAndAmountGreaterThan(finalOrgOrderId, orderId, 0);
                            if (order.checkOrderNeedQueryPay()) {
                                int dequeueCount = popMsg.getDequeueCount();
                                StorePay storePay = storePayDao.findByStoreIdAndStartEnabled(order.getStoreId(), true);
                                AllPayReverseResult reverseResult = new AllPayReverseResult();
                                if (dequeueCount > 30) {
                                    log.info("订单号{},操作{}", orderId, "进入关闭订单");
                                    WebCancelPayReq req = new WebCancelPayReq();
                                    switch (storePay.getChannel()) {
                                        case JL:
                                            reverseResult = jlService.jlCancelPay(orderId);
                                            break;
                                        case HUI_SHANG:
                                            reverseResult = hsService.cancelPay(orderId, req);
                                            break;
                                        case SAO_BEI:
                                            queue.deleteMessage(popMsg.getReceiptHandle());
                                            break;
                                        case HUI_FU:
                                            reverseResult = huiFuService.cancelPay(orderId);
                                            break;
                                        case SUI_XIN_FU:
                                            reverseResult = suiXinFuService.cancelPay(orderId);
                                            break;
                                    }
                                    if (reverseResult.isSuccess()) {
                                        queue.deleteMessage(popMsg.getReceiptHandle());
                                    }
                                } else {
                                    log.info("门店{}, 订单号{}, 操作{}, 支付渠道{}", order.getStoreId(), order.getId(), "支付轮训开始", storePay);
                                    if (dequeueCount > 1) {
                                        Thread.sleep(1000);
                                    }
                                    AllPayBaseQueryResult result;
                                    switch (storePay.getChannel()) {
                                        case JL:
                                            result = jlService.jlQueryPay(orderId, storePay.getMchId());
                                            log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "进入嘉联，支付轮训中", result);
                                            if (!result.isNeedQuery()) {
                                                if (result.isSuccess()) {
                                                    log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "进入嘉联，支付成功", result);
                                                    jlService.callbackForMicroPaymentSuccess(result);
                                                } else {
                                                    log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "进入嘉联，支付失败", result);
                                                    jlService.callbackForMicroPaymentFailed(orderId, result);
                                                }
                                                queue.deleteMessage(popMsg.getReceiptHandle());
                                            }
                                            break;
                                        case HUI_SHANG:
                                            result = hsService.queryMicroPay(orderId);
                                            log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "查询汇商支付返回结果", result);
                                            if (!result.isNeedQuery()) {
                                                if (result.isSuccess()) {
                                                    hsService.callbackForMicroPaymentSuccess(result);
                                                } else {
                                                    hsService.callbackForMicroPaymentFailed(orderId, result);
                                                }
                                                queue.deleteMessage(popMsg.getReceiptHandle());
                                            }
                                            break;
                                        case SAO_BEI:
                                            result = saoBeiService.saoBeiPayQuery(orderId, storePay);
                                            if (!result.isNeedQuery()) {
                                                if (result.isSuccess()) {
                                                    saoBeiService.saoBeiCallbackForMicroPaymentSuccess(result);
                                                } else {
                                                    saoBeiService.callbackForMicroPaymentFailed(orderId, result);
                                                }
                                                queue.deleteMessage(popMsg.getReceiptHandle());
                                            }
                                            break;
                                        case HUI_FU:
                                            result = huiFuService.huiFuQuery(orderId, storePay);
                                            log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "查询汇付支付返回结果", result);
                                            if (!result.isNeedQuery()) {
                                                if (result.isSuccess()) {
                                                    huiFuService.huifuCallbackForMicroPaymentSuccess(result);
                                                } else {
                                                    huiFuService.huifuCallbackForMicroPaymentFailed(orderId, result);
                                                }
                                                queue.deleteMessage(popMsg.getReceiptHandle());
                                            }
                                            break;
                                        case SUI_XIN_FU:
                                            result = suiXinFuService.suiXinFuQuery(orderId, storePay.getMchId());
                                            if (!result.getResultCode().equals("0002") && !result.getResultCode().equals("0001")) {
                                                log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "查询随心付支付返回结果", result);
                                                if (!result.isNeedQuery()) {
                                                    if (result.isSuccess()) {
                                                        suiXinFuService.suixinfuCallbackForMicroPaymentSuccess(result);
                                                    } else {
                                                        result.setOutTradeNo(orderId);
                                                        log.info("门店{}, 订单号{}, 操作{}, 支付返回结果{}", order.getStoreId(), order.getId(), "进入支付失败", result);
                                                        suiXinFuService.suixinfuCallbackForMicroPaymentFailed(orderId, result);
                                                    }
                                                    queue.deleteMessage(popMsg.getReceiptHandle());
                                                }
                                            }
                                            break;
                                    }

                                }
                            } else {
                                queue.deleteMessage(popMsg.getReceiptHandle());
                            }
                            return null;
                        });
                    }
                }
            } catch (Exception e) {
                log.error("Fail to process MNS message.", e);
            }
        }
    }

    @Autowired
    public void setClient(MNSClient client) {
        this.client = client;
    }

    @Autowired
    public void setPaymentService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    @Value("${mns.cloud-queue}")
    public void setCloudQueue(String cloudQueue) {
        this.cloudQueue = cloudQueue;
    }
}
